package xml;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import org.jdom.Element;
import org.jdom.JDOMException;

import start.Config;

/**
 * XML-Reader zum Auslesen von Rezepten aus XML-Files
 * @author Dennis Wittkoetter
 * @version 1.0
 *
 */
public class XMLRecipeReader extends XML {
	/**
	 * Konstruiert Reader-Objekt
	 * @param file	Dateiname
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public XMLRecipeReader(File file) throws JDOMException, IOException {
		super(file);
	}

	/**
	 * Konvertiert den Inhalt einer XML in ein fuer Tabellen lesbares Format
	 * @return	SortedMap (key=Rezeptname, value=Liste mit Kategorie und Bewertung) 
	 * 			mit allen in der XML vorhandenen Kategorien
	 * @throws IOException
	 * @throws JDOMException
	 */
	@SuppressWarnings("unchecked")
	public SortedMap<String,List<String>> convertToTable() throws JDOMException, IOException {
		update();
		List<Element>recipes = null;
		SortedMap<String, List<String>>map = new TreeMap<String, List<String>>();
		recipes = (List<Element>)root.getChildren();

		for (Element component : recipes) {
			List<String>str = new ArrayList<String>();
			String catList = allElemCategoriesToString(component);
			
			str.add(catList);
			//str.add(component.getChildText("category1"));
			str.add(component.getChildText("rating"));
			str.add(component.getChildText("id"));

			map.put(component.getChildText("name").toString(), str);
		}
        return map;
	}
	
	/**
	 * Ermittelt die hoechste ID aller in der XML gespeicherten Rezepte
	 * @return	Rezept-ID
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public int highestID() throws JDOMException, IOException {
		update();
		if(root.getChild("recipe") != null) {
			@SuppressWarnings("unchecked")
			List<Element> liste = (List<Element>)root.getChildren();
			int highest_id = Integer.parseInt(liste.get(liste.size()-1).getChild("id").getText());
			return highest_id;
		}
		return -1;
	}
	
	/**
	 * Liefert den Namen eines Rezepts durch Angabe der ID
	 * @param id	ID des gesuchten Rezeptnamens
	 * @return		Der gesuchte Rezeptname
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getName(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Rezeptname: "+comp.getChildText("name"));
				return comp.getChildText("name");
			}
		}
		return null;
	}
	
	/**
	 * Liefert eine Liste aller Zutaten, die vom Rezept mit der angegebenen ID verwendet werden
	 * @param id	ID des Rezepts
	 * @return		Zutatenliste
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	@SuppressWarnings("unchecked")
	public List<String> getIngredients(int id) throws JDOMException, IOException {
		update();
		List<String>retList = new ArrayList<String>();
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {	//ueber Rezepte laufen
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				Element ingredients = comp.getChild("ingredients");	//Zutaten-Child holen
				
				//ueber die einzelnen Zutaten laufen
				for (Element ing : (List<Element>)ingredients.getChildren("ingredient")) {
					retList.add(ing.getText());	//und in Rueckgabeliste speichern
				}
			}
		}
		
		if (Config.debugMode())	System.out.println("Zutatenliste: "+retList);
		return retList;
	}
	
	/**
	 * Liefert die erste Kategory, die einem Rezept mit der angegebenen ID zugeordnet ist
	 * @param id	ID des Rezepts
	 * @return		Name der Kategorie 1
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getCategory1(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Kategorie 1: "+comp.getChildText("category1"));
				return comp.getChildText("category1");
			}
		}
		return "keine";
	}
	
	/**
	 * Liefert die zweite Kategory, die einem Rezept mit der angegebenen ID zugeordnet ist
	 * @param id	ID des Rezepts
	 * @return		Name der Kategorie 2
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getCategory2(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Kategorie 2: "+comp.getChildText("category2"));
				return comp.getChildText("category2");
			}
		}
		return "keine";
	}
	
	/**
	 * Liefert die dritte Kategory, die einem Rezept mit der angegebenen ID zugeordnet ist
	 * @param id	ID des Rezepts
	 * @return		Name der Kategory 3
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getCategory3(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Kategory 3: "+comp.getChildText("category3"));
				return comp.getChildText("category3");
			}
		}
		return "keine";
	}
	
	/**
	 * Liefert den Zubereitungstext von dem Rezept mit der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Zubereitungstext
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getPreperationTxt(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Zubereitungstext: "+comp.getChildText("preperation"));
				return comp.getChildText("preperation");
			}
		}
		return null;
	}
	
	/**
	 * Liefert den Namen des Bildes eines Rezepts mit der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Bildname
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getImageName(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Bildname: "+comp.getChildText("imgname"));
				return comp.getChildText("imgname");
			}
		}
		return null;
	}
	
	/**
	 * Liefert den Namen des Thumbnails eines Rezepts mit der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Thumbnailname
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getThumbnailName(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Bildname: "+comp.getChildText("thumname"));
				return comp.getChildText("thumname");
			}
		}
		return null;
	}
	
	/**
	 * Liefert die Bewertung eines Rezepts anhand der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Bewertung
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public int getRating(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Bewertung: "+comp.getChildText("rating"));
				return Integer.parseInt(comp.getChildText("rating"));
			}
		}
		return -1;
	}
	
	/**
	 * Liefert die Personenzahl eines Rezepts anhand der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Anzahl der Personen
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public int getPersAmount(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Personenzahl: "+comp.getChildText("countPeople"));
				return Integer.parseInt(comp.getChildText("countPeople"));
			}
		}
		return -1;
	}
	
	/**
	 * Liefert die Tags eines Rezepts anhand der angegebenen ID
	 * @param id	ID des Rezepts
	 * @return		Tags
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public String getTags(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				if (Config.debugMode())	System.out.println("Tags: "+comp.getChildText("tags"));
				return comp.getChildText("tags");
			}
		}
		return null;
	}
	
	/**
	 * Liefert einen String aller Kategorien durch Kommas getrennt
	 * @param id	ID des Rezepts
	 * @return		Durch Kommas getrennte Kategorien
	 * @throws JDOMException
	 * @throws IOException
	 */
	public String getCategoryAll(int id) throws JDOMException, IOException {
		update();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {
			if (Integer.parseInt(comp.getChildText("id")) == id) {
				return allElemCategoriesToString(comp);
			}
		}
		return "keine";
		
	}
	
	/**
	 * Wandelt alle Kategorieeintraege eines Rezepts in einen
	 * Gesamt-String um. Die einzelnen Kategorien werden durch
	 * Kommas getennt.
	 * @param e	Element aus XML
	 * @return	alle Kategorieeintraege durch Kommas getrennt
	 * @throws JDOMException
	 * @throws IOException
	 */
	private String allElemCategoriesToString(Element e) throws JDOMException, IOException {
		update();
		String ret = "";
		if (!e.getChildText("category1").isEmpty()
		&& (!e.getChildText("category1").equals("keine")))
			ret += e.getChildText("category1");
		if (!e.getChildText("category2").isEmpty()
		&& (!e.getChildText("category2").equals("keine"))){
			if (!ret.isEmpty())
				ret += ", ";
			ret += e.getChildText("category2");
		}
		if (!e.getChildText("category3").isEmpty()
		&& (!e.getChildText("category3").equals("keine"))){
			if (!ret.isEmpty())
				ret += ", ";
			ret += e.getChildText("category3");
		}
		
		return ret;
	}
	
	/**
	 * Liefert eine Liste aller Rezeptnamen, deren Kategorien dem gesuchten Wert entsprechen
	 * @param s	Gesuchte Kategorie
	 * @return	Liste aller passenden Rezeptnamen
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	public List<String> getRecipesByCategory(String s) throws JDOMException, IOException {
		update();
		List<String>ret = new ArrayList<String>();
		@SuppressWarnings("unchecked")
		List<Element>recipes = (List<Element>)root.getChildren();
		
		for (Element comp : recipes) {				
			if (s.equalsIgnoreCase(comp.getChildText("category1"))
			||  s.equalsIgnoreCase(comp.getChildText("category2"))
			||  s.equalsIgnoreCase(comp.getChildText("category3"))) {
				if (Config.debugMode())	System.out.println("Kate: "	
										+comp.getChildText("category1")+", "
										+comp.getChildText("category2")+", "
										+comp.getChildText("category3")		);
				
				ret.add(comp.getChildText("name"));
			}		
		}
		return ret;
		
	}
}
